package com.ms.education.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.ms.education.constant.OrderConstant;
import com.ms.education.exceptionHandler.EduException;
import com.ms.education.order.entity.Order;
import com.ms.education.order.entity.eo.Classroom;
import com.ms.education.order.entity.eo.Course;
import com.ms.education.order.entity.eo.Teacher;
import com.ms.education.order.entity.eo.User;
import com.ms.education.order.mapper.OrderMapper;
import com.ms.education.order.service.OrderService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ms.education.order.service.feign.CourseFeignService;
import com.ms.education.order.service.feign.UcenterFeignService;
import com.ms.education.order.utils.ConstantWxPayUtils;
import com.ms.education.order.utils.OrderNoUtil;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * <p>
 * 订单 服务实现类
 * </p>
 *
 * @author ms
 * @since 2023-02-16
 */
@Service
public class OrderServiceImp extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private CourseFeignService courseFeignService;

    @Autowired
    private UcenterFeignService ucenterFeignService;

    @Autowired
    private RedissonClient redissonClient;

    @Override
    public String addOrder(Integer courseId, int userId, Integer type) {
        Order order = new Order();
        Course course = JSON.parseObject(JSON.toJSONString(courseFeignService.getCourseById(courseId, false, false).getData().get("course")), Course.class);
        User user = JSON.parseObject(JSON.toJSONString(ucenterFeignService.getById(userId).getData().get("user")), User.class);
        Teacher teacher = JSON.parseObject(JSON.toJSONString(ucenterFeignService.getTeacherById(course.getTeacherId()).getData().get("teacher")), Teacher.class);

        order.setOrderNo(OrderNoUtil.getOrderNo());
        order.setCourseId(courseId);
        order.setCourseTitle(course.getTitle());
        order.setCourseCover(course.getCover());
        order.setTeacherName(teacher.getName());
        order.setUserId(userId);
        order.setNickname(user.getNickname());
        order.setMobile(user.getMobile());
        order.setTotalFee(course.getPrice());
        order.setPayType(type);
        order.setStatus(OrderConstant.StatusEnum.STATUS_NO.getStatus());
        save(order);
        return order.getOrderNo();
    }

    @Override
    public Order getOrderByOrderNo(String orderNo) {
        RLock lock = redissonClient.getLock(orderNo);
        lock.lock();
        QueryWrapper<Order> wrapper = new QueryWrapper<Order>().eq("order_no", orderNo);
        Order order = getOne(wrapper);
        if (order == null) {
            throw new EduException(20001, "未查询到订单");
        }
        //为订单的过期时间续期,此处触发更新即可
        updateById(order);
        lock.unlock();
        return order;
    }

    @Override
    public Integer getOrderStatus(String orderNo) {
        QueryWrapper<Order> wrapper = new QueryWrapper<Order>().eq("order_no", orderNo).select("status");
        Order order = getOne(wrapper);
        if (order == null) {
            throw new EduException(20001, "该订单并不存在");
        }
        return order.getStatus();
    }

    @Override
    public void updateOrderStatus(String orderNo, Integer status) {
        UpdateWrapper<Order> wrapper = new UpdateWrapper<Order>().eq("order_no", orderNo).set("status", status);
        update(wrapper);
    }

    @Override
    public void deleteExpiredOrder() {
        baseMapper.deleteExpiredOrder(OrderConstant.expiredTime, OrderConstant.StatusEnum.STATUS_NO.getStatus());
    }

    @Override
    public List<Order> getAllOrdersOfUser(int userId) {
        QueryWrapper<Order> wrapper = new QueryWrapper<Order>().eq("user_id", userId).orderByDesc("gmt_modified");
        return list(wrapper);
    }

    @Override
    public boolean ifOrderPay(Integer courseId, Integer userId) {
        QueryWrapper<Order> wrapper = new QueryWrapper<Order>()
                .eq("course_id", courseId)
                .eq("user_id", userId)
                .eq("status", OrderConstant.StatusEnum.STATUS_YES.getStatus());
        return getOne(wrapper) != null;
    }

    @Override
    public void deleteNoPayOrder(Integer courseId, Integer userId) {
        UpdateWrapper<Order> wrapper = new UpdateWrapper<Order>()
                .eq("course_id", courseId)
                .eq("user_id", userId)
                .eq("status", OrderConstant.StatusEnum.STATUS_NO.getStatus());
        remove(wrapper);
    }

    @Override
    public String addOrderByClassId(Integer classId, Integer userId, Integer type) {
        Order order = new Order();
        User user = JSON.parseObject(JSON.toJSONString(ucenterFeignService.getById(userId).getData().get("user")), User.class);
        Classroom classroom = JSON.parseObject(JSON.toJSONString(courseFeignService.getClassById(classId).getData().get("classroom")), Classroom.class);
        order.setOrderNo(OrderNoUtil.getOrderNo());
        order.setClassId(classId);
        order.setCourseTitle(classroom.getName());
        order.setCourseCover(classroom.getCover());
        order.setUserId(userId);
        order.setNickname(user.getNickname());
        order.setMobile(user.getMobile());
        order.setTotalFee(classroom.getPrice());
        order.setPayType(type);
        order.setStatus(OrderConstant.StatusEnum.STATUS_NO.getStatus());
        save(order);
        return order.getOrderNo();
    }
}
